package com.mlst.smugmuglivewallpaper;

import java.io.BufferedInputStream;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Handler;
import android.os.SystemClock;
import android.service.wallpaper.WallpaperService;
import android.view.Display;
import android.view.SurfaceHolder;
import android.view.WindowManager;

public class Main extends WallpaperService {

    private final Handler mHandler = new Handler();

    @Override
    public Engine onCreateEngine() {
	return new WallpaperEngine();
    }

    class WallpaperEngine extends Engine {

	private boolean mVisible;
	private ArrayList<Bitmap> imageBitmaps = new ArrayList<Bitmap>();
	private Paint clearPaint;

	// image should be centered wrt to the device's screen
	private float mCenterX;
	private float mCenterY;

	// max width and height of the device
	private int maxWidth;
	private int maxHeight;

	// the alpha component of the photo. We need this to adjust the opacity
	// for the fade out effect
	private int imageAlpha = 255;
	private Bitmap currentBitmap;
	private float startTime;
	private int currentPhotoIndex;

	private final Runnable mDrawImage = new Runnable() {
	    public void run() {
		drawImage();
	    }
	};

	public WallpaperEngine() {
	    Display display = ((WindowManager) getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
	    maxWidth = display.getWidth();
	    maxHeight = display.getHeight();

	    clearPaint = new Paint(Paint.FILTER_BITMAP_FLAG);

	    try {
		ArrayList<String> images = ConnectionHelper.loadImages();
		for (String image : images) {
		    final Bitmap bm = fetchBitmap(image);
		    if(bm != null){
			imageBitmaps.add(bm);
		    }
		}

		startTime = SystemClock.elapsedRealtime();
	    } catch (Exception e) {
		e.printStackTrace();
	    }
	}

	// download the specified image and convert it into bitmap
	private Bitmap fetchBitmap(String image) {
	    Bitmap bm = null;
	    try {
		final URL aURL = new URL(image);
		final InputStream is2 = aURL.openConnection().getInputStream();
		final BufferedInputStream bis = new BufferedInputStream(is2, 16384);
		bm = BitmapFactory.decodeStream(bis);
		bis.close();
	    } catch (Exception e) {
		e.printStackTrace();
	    }

	    return bm;
	}

	public void onCreate(SurfaceHolder surfaceHolder) {
	    super.onCreate(surfaceHolder);
	    setTouchEventsEnabled(false); // disable touch events
	}

	@Override
	public void onDestroy() {
	    super.onDestroy();
	    mHandler.removeCallbacks(mDrawImage);
	}

	@Override
	public void onVisibilityChanged(boolean visible) {
	    mVisible = visible;
	    if (visible) {
		drawImage();
	    } else {
		mHandler.removeCallbacks(mDrawImage);
	    }
	}

	@Override
	public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) {
	    super.onSurfaceChanged(holder, format, width, height);

	    drawImage();
	}

	@Override
	public void onSurfaceDestroyed(SurfaceHolder holder) {
	    super.onSurfaceDestroyed(holder);
	    mVisible = false;
	    mHandler.removeCallbacks(mDrawImage);
	}

	@Override
	public void onOffsetsChanged(float xOffset, float yOffset, float xStep, float yStep, int xPixels, int yPixels) {
	    drawImage();
	}

	private void drawImage() {
	    final SurfaceHolder holder = getSurfaceHolder();

	    Canvas c = null;
	    try {
		c = holder.lockCanvas();
		if (c != null) {
		    drawBitmap(c);
		}
	    } finally {
		if (c != null)
		    holder.unlockCanvasAndPost(c);
	    }

	    // Reschedule the next redraw
	    mHandler.removeCallbacks(mDrawImage);

	    if (mVisible) {
		mHandler.post(mDrawImage);
	    }

	}

	private void drawBitmap(Canvas c) {
	    
	    if(imageBitmaps.size() == 0){
		return;
	    }

	    boolean toggleImage = false;

	    float currentTime = SystemClock.elapsedRealtime();
	    int elapsed = Math.round((currentTime - startTime) / 1000);

	    if (elapsed >= 5) {
		imageAlpha -= 25;
		if (imageAlpha <= 50) {
		    toggleImage = true;
		    startTime = currentTime;
		}
	    }

	    c.save();
	    c.drawColor(Color.BLACK);

	    clearPaint.setAlpha(imageAlpha);

	    if (toggleImage) {
		imageAlpha = 255;

		Bitmap temp = imageBitmaps.get(currentPhotoIndex++);
		if (temp != null) {
		    currentBitmap = temp;
		}

	    }

	    if (currentBitmap == null) {
		currentBitmap = imageBitmaps.get(currentPhotoIndex++);
	    }

	    mCenterX = getMidpoint(maxWidth, currentBitmap.getWidth());
	    mCenterY = getMidpoint(maxHeight, currentBitmap.getHeight());

	    currentBitmap = ImageUtilities.scaleAndFrame(currentBitmap, maxWidth, maxHeight);

	    c.drawBitmap(currentBitmap, mCenterX, mCenterY, clearPaint);
	    c.restore();

	    // reset our index after we reach the end of our bitmap list
	    if (currentPhotoIndex >= imageBitmaps.size()) {
		currentPhotoIndex = 0;
	    }

	}
    }

    private int getMidpoint(int x1, int x2) {
	return (x1 - x2) / 2;
    }

}